﻿package ms.display
{
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.events.Event;
	
	import ms.core.display.ButtonType;
	import ms.core.display.IButton;
	import ms.utils.ButtonManager;
	import ms.events.ButtonEvent;
	
	public class Button extends MovieClip implements IButton
	{
		private var _doubleClick:Boolean = false;
		private var _alwaysOn:Boolean = false;
		private var _bubbling:Boolean = true;
		private var _active:Boolean = false;
		private var _data:Object;
		private var _type:String = ButtonType.NORMAL;
		
		public function Button():void 
		{
			this.addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, init);
			ButtonManager.addButton(this);
			this.buttonMode = true;
			setListeners();
		}
		
		/*  Setters and getters
		 */
		 
		public function set doubleClick(value:Boolean):void
		{
			_doubleClick = value;
			updateBehavior();
		}

		public function get doubleClick():Boolean
		{
			return _doubleClick;
		}
		
		public function set alwaysOn(value:Boolean):void
		{
			_alwaysOn = value;
		}

		public function get alwaysOn():Boolean
		{
			return _alwaysOn;
		}
		
		public function set type(value:String):void
		{
			_type = value;
			(value == ButtonType.CLOSE) ? this.alwaysOn = true : null;
		}

		public function get type():String
		{
			return _type;
		}
		
		public function set bubbles(value:Boolean):void
		{
			_bubbling = value;
		}

		public function get bubbles():Boolean
		{
			return _bubbling;
		}
		
		public function set active(value:Boolean):void
		{
			_active = value;
		}

		public function get active():Boolean
		{
			return _active;
		}
		
		public function set data(value:Object):void
		{
			if(!_data) _data = {};
			_data = value;
		}

		public function get data():Object
		{
			return _data;
		}
		
		/*  Core
		 */
		
		private function setListeners():void
		{
			this.addEventListener(Event.REMOVED_FROM_STAGE, dispose);
			this.addEventListener(MouseEvent.ROLL_OVER, rollOver);
			this.addEventListener(MouseEvent.ROLL_OUT, rollOut);
			this.addEventListener(MouseEvent.CLICK, click);
		}
		
		private function removeListeners():void
		{
			this.removeEventListener(Event.REMOVED_FROM_STAGE, dispose);
			this.removeEventListener(MouseEvent.ROLL_OVER, rollOver);
			this.removeEventListener(MouseEvent.ROLL_OUT, rollOut);
			this.removeEventListener(MouseEvent.CLICK, click);
		}
		
		protected function click(e:MouseEvent = null):void
		{
			this.disable();
			this.active = true;
			switch(type) {
				case ButtonType.NORMAL:
				 this.dispatchEvent(new ButtonEvent(ButtonEvent.CLICK, bubbles));
				 break;
				case ButtonType.CLOSE:
				 this.dispatchEvent(new ButtonEvent(ButtonEvent.CLOSE, bubbles));
				 break;
			}
		}
		
		public function disable():void
		{
			if(!alwaysOn) {
				(doubleClick) ? this.removeEventListener(MouseEvent.DOUBLE_CLICK, click) : this.removeEventListener(MouseEvent.CLICK, click);
				this.removeEventListener(MouseEvent.ROLL_OVER, rollOver);
				this.removeEventListener(MouseEvent.ROLL_OUT, rollOut);
				this.buttonMode = false;
			}
		}
		
		public function restore():void
		{
			if(!alwaysOn || active) {
				(doubleClick) ? this.addEventListener(MouseEvent.DOUBLE_CLICK, click) : this.addEventListener(MouseEvent.CLICK, click);
				this.addEventListener(MouseEvent.ROLL_OVER, rollOver);
				this.addEventListener(MouseEvent.ROLL_OUT, rollOut);
				this.buttonMode = true;
				this.active = false;
			}
		}
		
		protected function rollOver(e:MouseEvent = null):void
		{
			this.dispatchEvent(new ButtonEvent(ButtonEvent.ROLL_OVER, bubbles));
		}
		
		protected function rollOut(e:MouseEvent = null):void
		{
			this.dispatchEvent(new ButtonEvent(ButtonEvent.ROLL_OUT, bubbles));
		}
		
		
		private function updateBehavior():void
		{
			if(doubleClick)
			{
				this.removeEventListener(MouseEvent.CLICK, click);
				this.addEventListener(MouseEvent.DOUBLE_CLICK, click);
				this.doubleClickEnabled = true;
			} else {
				this.removeEventListener(MouseEvent.DOUBLE_CLICK, click);
				this.addEventListener(MouseEvent.CLICK, click);
				this.doubleClickEnabled = false;
			}
		}
		
		private function dispose(e:Event):void
		{
			removeListeners();
		}
	}
}